#!/usr/bin/env python3
"""
代码复杂度审查MCP工具
分析项目代码复杂度
"""

import asyncio
import logging
from typing import Dict, Any
from pathlib import Path

from biz.cmd.func.complexity import ComplexityReviewFunc


class ComplexityReviewTool:
    """
    代码复杂度审查工具
    分析项目代码的复杂度
    """
    
    def __init__(self):
        self.complexity_func = None
    
    def _get_complexity_func(self):
        """延迟初始化复杂度分析功能"""
        if self.complexity_func is None:
            self.complexity_func = ComplexityReviewFunc()
        return self.complexity_func
    
    def validate_directory(self, directory: str) -> bool:
        """
        验证目录是否存在
        """
        try:
            return Path(directory).resolve().is_dir()
        except Exception:
            # 使用日志记录错误而不是print
            logging.error("验证目录时出错", exc_info=True)
            return False
    
    def format_complexity_result(self, results: list) -> str:
        """
        格式化复杂度分析结果
        """
        if not results:
            return "没有找到可分析的代码文件"
        
        # 确保所有字符串都使用ASCII字符，避免Unicode编码问题
        report = "## 代码复杂度分析报告\n\n"
        report += f"### 复杂度最高的 {len(results)} 个函数\n\n"
        
        for i, result in enumerate(results, 1):
            report += f"#### {i}. {result.name}\n"
            report += f"- **文件**: `{result.filename}`\n"
            report += f"- **起始行**: {result.start_line}\n"
            report += f"- **圈复杂度**: {result.cyclomatic_complexity}\n"
            report += f"- **代码行数**: {result.nloc}\n"
            report += f"- **参数个数**: {result.parameter_count}\n"
            report += f"- **Token数量**: {result.token_count}\n\n"
        
        # 添加统计信息
        total_complexity = sum(r.cyclomatic_complexity for r in results)
        avg_complexity = total_complexity / len(results)
        max_complexity = max(r.cyclomatic_complexity for r in results)
        
        report += "### 统计信息\n\n"
        report += f"- **总复杂度**: {total_complexity}\n"
        report += f"- **平均复杂度**: {avg_complexity:.2f}\n"
        report += f"- **最高复杂度**: {max_complexity}\n\n"
        
        # 添加建议
        report += "### 优化建议\n\n"
        
        high_complexity_count = len([r for r in results if r.cyclomatic_complexity > 10])
        if high_complexity_count > 0:
            report += f"- 发现 {high_complexity_count} 个高复杂度函数(复杂度 > 10)，建议重构\n"
        
        medium_complexity_count = len([r for r in results if 5 < r.cyclomatic_complexity <= 10])
        if medium_complexity_count > 0:
            report += f"- 发现 {medium_complexity_count} 个中等复杂度函数(复杂度 5-10)，可考虑优化\n"
        
        low_complexity_count = len([r for r in results if r.cyclomatic_complexity <= 5])
        if low_complexity_count > 0:
            report += f"- {low_complexity_count} 个函数复杂度较低(复杂度 <= 5)，维护性良好\n"
        
        report += "\n### 复杂度等级说明\n\n"
        report += "- **1-5**: 简单，易于理解和维护\n"
        report += "- **6-10**: 中等复杂，需要注意\n"
        report += "- **11-20**: 复杂，建议重构\n"
        report += "- **21+**: 极其复杂，强烈建议重构\n"
        
        return report
    
    async def execute(self, arguments: Dict[str, Any]) -> str:
        """
        执行代码复杂度分析
        """
        try:
            logging.info("[ComplexityReviewTool] 开始执行代码复杂度分析")
            logging.info(f"[ComplexityReviewTool] 接收到的参数: {arguments}")
            
            directory = arguments.get("directory")
            top_n = arguments.get("top_n", 10)
            
            logging.info(f"[ComplexityReviewTool] 解析参数: directory={directory}, top_n={top_n}")
            
            if not directory:
                logging.error("[ComplexityReviewTool] 错误: 缺少必需参数 directory")
                return "错误: 缺少必需参数 directory"
            
            # 验证目录
            logging.info(f"[ComplexityReviewTool] 验证目录: {directory}")
            if not self.validate_directory(directory):
                logging.error(f"[ComplexityReviewTool] 错误: 目录 '{directory}' 不存在或无法访问")
                return f"错误: 目录 '{directory}' 不存在或无法访问"
            
            # 获取复杂度分析功能实例
            logging.info("[ComplexityReviewTool] 获取复杂度分析功能实例")
            complexity_func = self._get_complexity_func()
            
            # 设置参数
            logging.info("[ComplexityReviewTool] 设置参数到ComplexityReviewFunc实例")
            complexity_func.directory = directory
            complexity_func.top_n = top_n
            
            # 异步执行复杂度分析
            logging.info("[ComplexityReviewTool] 开始异步执行复杂度分析")
            loop = asyncio.get_event_loop()
            results = await loop.run_in_executor(
                None, 
                complexity_func.process
            )
            logging.info(f"[ComplexityReviewTool] 复杂度分析完成，获取到 {len(results) if results else 0} 个结果")
            
            # 格式化结果
            logging.info("[ComplexityReviewTool] 开始格式化结果")
            formatted_result = self.format_complexity_result(results)
            logging.info("[ComplexityReviewTool] 格式化完成，准备返回结果")
            logging.info(f"[ComplexityReviewTool] 返回结果类型: {type(formatted_result)}")
            logging.info(f"[ComplexityReviewTool] 返回结果长度: {len(formatted_result) if formatted_result else 0}")
            
            # 确保返回的是字符串
            if not isinstance(formatted_result, str):
                logging.error(f"[ComplexityReviewTool] 错误: 返回结果不是字符串类型，而是 {type(formatted_result)}")
                return f"错误: 返回结果格式不正确，请联系管理员"
            
            # 确保字符串只包含ASCII字符，避免编码问题
            try:
                # 尝试使用ASCII编码，这会移除所有非ASCII字符
                ascii_result = formatted_result.encode('ascii', 'replace').decode('ascii')
                logging.info("[ComplexityReviewTool] 已将结果转换为ASCII编码")
                return ascii_result
            except Exception as e:
                logging.error(f"[ComplexityReviewTool] 编码转换失败: {str(e)}")
                # 如果转换失败，返回原始结果
                return formatted_result
            
        except Exception as e:
            logging.error(f"[ComplexityReviewTool] 执行失败: {str(e)}")
            import traceback
            logging.error(f"[ComplexityReviewTool] 错误详情: {traceback.format_exc()}")
            return f"代码复杂度分析执行失败: {str(e)}"